{-# LANGUAGE TupleSections, OverloadedStrings, CPP #-}
module Handler.Home where

import Import
import Text.Julius
import Handler.CommonRoutes

defaultSizeExponents :: (Int, Int)
defaultSizeExponents = (7,7)

canvasSize :: (Int, Int)
canvasSize = (640, 480)

-- Displays tessendorf water, using a grid of 2^width * 2^height points
-- and displays a form to change those parameters.
getHomeR :: Handler RepHtml
getHomeR = defaultLayout $ homeWidget defaultSizeExponents

postHomeR :: Handler RepHtml
postHomeR = defaultLayout $ do
  ((result, widget), enctype) <- lift $ runFormPost $ parametersForm Nothing
  case result of
    FormSuccess size -> homeWidget size
    _ -> homeWidget defaultSizeExponents

homeWidget :: (Int, Int) -> Widget
homeWidget (widthExponent, heightExponent) = do
  waterWidget widthExponent heightExponent
  parametersFormWidget widthExponent heightExponent

-- Displays tessendorf water, using a grid of 2^width * 2^height points.
waterWidget :: Int -> Int -> Widget
waterWidget widthExponent heightExponent = do
  canvasId <- lift $ newIdent
  let
    fftVSRoute = StaticR shaders_fft_vert
    fftFSRoute = StaticR shaders_fft_frag
    lightingVSRoute = StaticR shaders_lighting_vert
    lightingFSRoute = StaticR shaders_lighting_frag
  [whamlet|
   <canvas ##{canvasId} width=640 height=480>
     Your browser does not support Html5 canvas, sorry :-(.
   |]
  addScript jqueryRoute
  addScript glMatrixRoute
#if PRODUCTION
  toWidget $(juliusFile "templates/tessendorfWater.julius")
#else
  toWidget $(juliusFileReload "templates/tessendorfWater.julius")
#endif

-- Displays a form for changing the width and height of the water mesh.
parametersFormWidget :: Int -> Int -> Widget
parametersFormWidget widthExponent heightExponent = do
  ((_, widget), enctype) <- lift $ runFormPost 
                            $ parametersForm $ Just (widthExponent, heightExponent)
  [whamlet|
   <form .well method=post action=@{HomeR} enctype=#{enctype}>
     ^{widget}
     <button type=submit .btn>
       Change mesh size
   |]

parametersForm :: Maybe (Int, Int) -> Html 
                  -> MForm App App
                  (FormResult (Int, Int), Widget)
parametersForm mSize =
  renderBootstrap $ (,)
  <$> areq intField "Width" (fst <$> mSize)
  <*> areq intField "Height" (snd <$> mSize)
